# 导包
from collections import UserString
from datetime import tzinfo
from functools import wraps
from logging import info
from operator import mod
from os import write
from peewee import EXCEPTIONS, NoopModelSelect
from redis.client import Redis
import tornado.web

from bson.objectid import ObjectId

# 服务器
from tornado import httpserver
from werkzeug.datastructures import Headers

# 导入基础类
from base import BaseHandler

# 导入数据库操作类
from db import database, User, myser, MyMongo, Talk, Sub_Talk, Subject, Comment

mymongo = MyMongo()

import datetime

# python的时区库
import pytz

# 设置时区
tzinfo = pytz.timezone('Asia/Shanghai')

# 异步执行库
import peewee_async
import hashlib

import json, random

from tools import ret_json, send_mail, MyJwt, SendSms

import random
import redis

import re, asyncio
import requests

# 绘图库
from PIL import ImageDraw
from PIL import Image

# io库
import io

import time, os

# 导入工厂类
from test_desgin import SimpleFactory

from tools import Flow, ImgList

# 导入聚合函数查询库
from peewee import fn


# 图集接口
class Img(BaseHandler):

    # 修改图集
    async def put(self):
        # 帖子id
        sid = self.get_argument('sid', None)
        sid = int(sid)
        # 图集列表
        imglist = self.get_argument('imglist', None)
        imglist = eval(imglist)
        myimg = ImgList()
        myimg.update_one(sid, imglist)

        return self.write(ret_json({'code': 200, 'meg': '修改图集成功'}))

    # 插入图集
    async def post(self):
        # 帖子id
        sid = self.get_argument('sid', None)
        sid = int(sid)
        # 图集列表
        imglist = self.get_argument('imglist', None)
        imglist = eval(imglist)
        # print(imglist,type(imglist))
        # 入库操作
        myimg = ImgList()
        # 查询去重
        # img = myimg.get_img(sid)
        # if img:
        #     return self.write(ret_json({'code':403,'meg':'该帖子已存在'}))
        try:
            myimg.insert_one(sid, imglist)
            return self.write(ret_json({'code': 200, 'meg': '插入图集成功'}))
        except Exception as e:
            return self.write(ret_json({'code': 403, 'meg': '该帖子已存在'}))


# redis判断关注类
class IfConcern(BaseHandler):

    # 查询
    async def get(self):
        # 本用户id
        uid = self.get_argument('uid')
        # 查看是否关注人的id
        fuid = self.get_argument('fuid')
        flow = Flow()
        # print(uid,fuid)
        res = flow.ifflow(uid, fuid)

        if res == True:
            # 已经关注过
            return self.write(ret_json({'code': 200, 'meg': res}))
        else:
            return self.write(ret_json({'code': 200, 'meg': res}))

    # 取消关注
    async def delete(self):
        # 本用户id
        uid = self.get_argument('uid')
        # 查看是否关注人的id
        fuid = self.get_argument('fuid')
        flow = Flow()
        # print(uid,fuid)
        flow.del_flow(uid, fuid)
        return self.write(ret_json({'code': 200, 'meg': '取消关注成功!'}))

    # 关注信息
    async def post(self):
        # 本用户id
        uid = self.get_argument('uid')
        # 查看是否关注人的id
        fuid = self.get_argument('fuid')
        flow = Flow()
        # print(uid,fuid)
        flow.set_flow(uid, fuid, 1)
        return self.write(ret_json({'code': 200, 'meg': '关注成功!'}))


# 创建帖子类
class SubjectView(BaseHandler):

    # 创建
    async def post(self):
        uid = self.get_argument('uid', None)
        info = self.get_argument('info', None)
        # 帖子类型   0默认公开
        type = self.get_argument('type', 0)
        # 图片
        img = self.get_argument('img', None)
        # 视频
        video = self.get_argument('video', None)
        # print(video,'video++++++++++++++++++++++++++++++')

        # print(info)

        # 解析帖子内容,查看参与话题
        talks = re.findall(r'#([\w ]+)#', info)

        # pattern = re.findall(r"@([\w]+)[' ']",info)

        # if pattern:
        #     for i in pattern:
        #         res = await self.application.objects.get(User,username=i)
        #         info = re.sub(i, "<a href= 'http://localhost:8080/userinfo/?uid=%s'>\g<0></a>" % res.id, info)

        if talks:

            # 入库操作
            for i in talks:
                try:
                    await self.application.objects.create(Talk, title=i)
                except Exception as e:
                    pass

        # 添加帖子
        sub = await self.application.objects.create(Subject, uid=uid, info=info, type=type, img=img, video=video)

        # 添加到关联表中,反查逻辑
        if talks:
            for i in talks:
                talkid = await self.application.objects.get(Talk, title=i)

                # 入库
                await self.application.objects.create(Sub_Talk, sid=sub.id, tid=talkid.id)

        return self.write(ret_json({'code': 200, 'meg': '创建帖子成功', 'sid': sub.id}))

    # 查询用户信息
    async def get(self):
        # 用户id
        uid = self.get_argument('uid', None)
        # 帖子id
        tid = self.get_argument('id', None)

        # 当前页
        page = self.get_argument('page', 1)

        page = int(page)
        # print(uid)

        comments = await self.application.objects.execute(
            Comment.select(Comment.sid, fn.COUNT(Comment.id).alias('total')).group_by(Comment.sid))
        comment_dict = {}
        for i in comments:
            print(i.sid, i.total)
            comment_dict[i.sid] = i.total
        print(comment_dict)
        if tid:
            res = await self.application.objects.get(Subject, id=tid)
            res = myser(res)
            return self.write(ret_json(res))
        # 异步查询     分页器           当前页          每页多少条数据
        res = await self.application.objects.execute(
            Subject.select().where(Subject.uid == int(uid)).order_by(-Subject.id).paginate(page, 3))

        # print(res[0].info)
        list1 = [myser(i) for i in res]
        username_dict = {}

        # 正则匹配解析帖子内容,查看有多少@用户
        for i in list1:
            # 增加评论数
            i['comment'] = comment_dict.get(i['id'], 0)

            users = re.findall(r'@([\w]+)', i['info'])
            # 查询用户的id
            for user in users:
                try:
                    res = await self.application.objects.get(User, username=user)
                    # 用户名为key     id为值  {'夜玉兮':50}
                    username_dict[user] = res.id

                    i['info'] = i['info'].replace("@%s" % user,
                                                  "<a href= 'http://localhost:8080/userinfo/?uid=%s'>@%s</a>" % (
                                                      username_dict[user], user))
                except Exception as e:
                    pass

            # # 替换逻辑
            # res = await self.application.objects.get(User,username=j)
            # info = re.sub(r"@([\w]+)[' ']", "<a href= 'http://localhost:8080/userinfo/?uid=%s'>\g<0></a>" % res.id, i['info'])                                

        # 查询图集
        mymongo = MyMongo('img')
        imgs = mymongo.find({})
        imgs_dict = {}
        for i in imgs:
            imgs_dict[i['sid']] = i['imglist']

        for i in list1:
            print(i['id'])

            i['imglist'] = imgs_dict.get(i['id'], [])
        print(imgs_dict)
        # print(list1)
        return self.write(ret_json({'code': 200, 'list': list1}))

    # 删除当前帖子
    async def delete(self):
        id = self.get_argument('id', None)

        id = int(id)
        # sub = await self.application.objects.get(Subject,id=id)
        Subject.delete().where(Subject.id == int(id)).execute()
        myimg = ImgList()
        # 删除本地文件

        imglist = myimg.get_img(id)
        for i in imglist:
            try:
                os.remove('./static/%s' % i)
            except Exception as e:
                pass
        # 删除对应图集

        myimg.del_img(id)

        try:
            Subject.delete().where(Subject.id == int(id)).execute()
        except Exception as e:
            return self.write(ret_json({'code': 403, 'meg': '没有此帖子'}))
        return self.write(ret_json({'code': 200, 'meg': '帖子删除成功'}))

    async def put(self):
        id = self.get_argument('id')
        info = self.get_argument('info')
        res = await self.application.objects.get(Subject, id=id)
        res.info = info
        await self.application.objects.update(res)
        return self.write(ret_json({'code': 200, 'meg': '修改成功'}))


# 可@用户列表
class GetUser(BaseHandler):
    async def get(self):
        # 用户id
        id = self.get_argument('id', None)

        userlist = []

        # 排除查询
        res = await self.application.objects.execute(User.select().where(User.id != id))
        userlist = [myser(i) for i in res]
        return self.write(ret_json({'code': 200, 'userlist': userlist}))


# 单帖子数据
class OneSub(SubjectView):

    async def get(self):
        sid = self.get_argument('sid', None)
        # 查询数据
        try:
            res = await self.application.objects.get(Subject.select().where(Subject.id == sid))
        except Exception as e:
            return self.write(ret_json({'code': 403, 'meg': '您所请求不存在'}))
        # 序列化操作
        res = myser(res)
        print(res)
        # 获取图集
        myimg = ImgList()
        imglist = myimg.get_img(int(sid))
        print(imglist)

        # 赋值
        res['imglist'] = imglist
        return self.write(ret_json(res))
        # return self.write('ok')


# 帖子评论接口
class CommentView(BaseHandler):

    # 添加评论
    async def post(self):
        sid = self.get_argument("sid", None)
        uid = self.get_argument("uid", None)
        content = self.get_argument("comment", None)
        touid = self.get_argument("touid", 0)

        # 入库
        comment = await self.application.objects.create(Comment, sid=sid, uid=uid, content=content, touid=touid)

        return self.write(ret_json({"code": 200, "msg": "评论成功", "cid": comment.id}))

    # 根据点击数据获取评论信息
    async def get(self):
        sid = self.get_argument("sid", None)
        # 获取评论
        comments = await self.application.objects.execute(
            Comment.select().where(Comment.sid == sid).order_by(-Comment.id))

        # 序列化
        comments = [myser(x) for x in comments]
        # 添加用户信息
        for i in comments:
            try:
                user = await self.application.objects.get(User, id=i["uid"])
            except Exception as e:
                pass
            else:
                i["username"] = user.username
                i["userimg"] = user.img
                i["uid"] = user.id
            try:
                huifu = await self.application.objects.get(User, id=i["touid"])
            except Exception as e:
                pass
            else:
                i['touid'] = huifu.username
        print(comments, '数据+++++++++')

        return self.write(ret_json(comments))
